home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Programming / OUI / cstring.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  16.2 KB  |  528 lines

  1. // $Id: cstring.cc 1.4 1998/04/08 15:09:56 dlorre Exp $
  2. #include <graphics/gfxmacros.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/classes.h>
  5. #include <intuition/classusr.h>
  6. #include <intuition/imageclass.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <intuition/icclass.h>
  9. #include <intuition/cghooks.h>
  10. #include <libraries/gadtools.h>
  11.  
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <mydebug.h>
  15.  
  16. #include "screen.h"
  17. #include "window.h"
  18. #include "gadgets/cstring.h"
  19. #include "gadgets/eclass.h"
  20. #include "gadgetlist.h"
  21.  
  22. #include <proto/exec.h>
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <proto/utility.h>
  26. #include <clib/alib_protos.h>
  27. #include <compiler.h>
  28.  
  29. Class *BOOPSIELabel ;
  30. int InitELabel(void) ;
  31. void FreeELabel(void) ;
  32.  
  33. extern "C" STDARGS ULONG HookEntry() ;
  34.  
  35. // ========================================================================
  36. // ==========================  CSTRING CLASS ==============================
  37. // ========================================================================
  38.  
  39.  
  40. cstring::cstring(gadgetlist *gl,
  41.                  void (window::*func)(gadget *, unsigned long, unsigned short),
  42.                  const char *t,
  43.                  const char *text,
  44.                  long border, long place, char style) : gadget(gl, func)
  45. {
  46. int i, l1, l2 ;
  47. BOOL underset = FALSE ;
  48. UWORD *pens = gl->win->ws->drawinfo->dri_Pens;
  49. short gleft, gtop, gwidth, gheight ;
  50.  
  51.     gl->ng->ng_Flags = place ;
  52.     InitELabel() ;
  53.  
  54.     gleft = gl->ng->ng_LeftEdge ;
  55.     gtop = gl->ng->ng_TopEdge ;
  56.     gwidth = gl->ng->ng_Width ;
  57.     gheight = gl->ng->ng_Height ;
  58.  
  59.     if (style & BOTTOMCSTRING)
  60.         gtop = short(-gtop) ;
  61.     if (style & RIGHTCSTRING)
  62.         gleft = short(-gleft) ;
  63.     if (style & WIDTHCSTRING)
  64.         gwidth = short(-gwidth) ;
  65.     if (style & HEIGHTCSTRING)
  66.         gheight = short(-gheight) ;
  67.  
  68.  
  69.     if (t) {
  70.  
  71.         it1 = new IntuiText ;
  72.         it2 = new IntuiText ;
  73.         it3 = new IntuiText ;
  74.  
  75.         plain = new TTextAttr ;
  76.         underline = new TTextAttr ;
  77.  
  78.         it1->FrontPen = it2->FrontPen = it3->FrontPen = gl->win->ws->drawinfo->dri_Pens[(place&NG_HIGHLABEL)?HIGHLIGHTTEXTPEN:TEXTPEN] ;
  79.         it1->BackPen = it2->BackPen = it3->BackPen = 0 ;
  80.         it1->DrawMode = it2->DrawMode = it3->DrawMode = JAM1 ;
  81.  
  82.         norm1 = new char[strlen(t)+1] ;
  83.         norm2 = new char[strlen(t)+1] ;
  84.         under = new char[2] ;
  85.  
  86.         underkey(t) ;
  87.  
  88.         CopyMem(gl->win->ws->scr->Font, plain, sizeof(struct TTextAttr)) ;
  89.         CopyMem(gl->win->ws->scr->Font, underline, sizeof(struct TTextAttr)) ;
  90.         underline->tta_Style |= FSF_UNDERLINED ;
  91.         font = OpenFont((TextAttr *)underline) ;
  92.  
  93.         for (i=l1=l2=0; t[i]; i++) {
  94.             if (t[i] == '_') {
  95.                 if (t[i+1]) under[0] = t[++i] ;
  96.                 underset = TRUE ;
  97.             }
  98.             else {
  99.                 if (underset) {
  100.                     norm2[l2++] = t[i] ;
  101.                 }
  102.                 else {
  103.                     norm1[l1++] = t[i] ;
  104.                 }
  105.             }
  106.         }
  107.         norm1[l1] = '\0' ;
  108.         norm2[l2] = '\0' ;
  109.         under[1] = '\0' ;
  110.  
  111.         if (l1) {
  112.             it1->IText = (UBYTE *)norm1 ;
  113.             it1->ITextFont = (TextAttr *)plain ;
  114.             if (underset) {
  115.                 it1->NextText = it2 ;
  116.                 it2->LeftEdge = short(IntuiTextLength(it1)) ;
  117.                 it2->IText = (UBYTE *)under ;
  118.                 it2->ITextFont = (TextAttr *)underline ;
  119.                 if (l2) {
  120.                     it2->NextText = it3 ;
  121.                     it3->LeftEdge = short(it2->LeftEdge + IntuiTextLength(it2)) ;
  122.                     it3->IText = (UBYTE *)norm2 ;
  123.                     it3->ITextFont = (TextAttr *)plain ;
  124.                 }
  125.             }
  126.         }
  127.         else if (underset) {
  128.             it1->IText = (UBYTE *)under ;
  129.             it1->ITextFont = (TextAttr *)underline ;
  130.             it1->NextText = it2 ;
  131.             it2->LeftEdge = short(IntuiTextLength(it1)) ;
  132.             it2->IText = (UBYTE *)norm2 ;
  133.             it2->ITextFont = (TextAttr *)plain ;
  134.         }
  135.     }
  136.     gad = gl->gad = (Gadget *)NewObject(BOOPSIELabel, NULL,
  137.             GA_ID,          id,
  138.             GA_Top,         gtop,
  139.             GA_Left,        gleft,
  140.             GA_Width,       gwidth,
  141.             GA_Height,      gheight,
  142.  
  143.             (style & BOTTOMCSTRING)?GA_RelBottom:TAG_IGNORE,   TRUE,
  144.             (style & RIGHTCSTRING)?GA_RelRight:TAG_IGNORE,     TRUE,
  145.             (style & WIDTHCSTRING)?GA_RelWidth:TAG_IGNORE,     TRUE,
  146.             (style & HEIGHTCSTRING)?GA_RelHeight:TAG_IGNORE,   TRUE,
  147.  
  148.             GA_Previous,    gl->gad,
  149.             GA_IntuiText,   it1 ,
  150.             GA_Border,      border,
  151.             GA_Text,        text,
  152.             EGA_Flags,      place,
  153.             EGA_TextAttr,   gl->ng->ng_TextAttr,
  154.             EGA_XPens,      gl->win->ws->xpens,
  155.             EGA_GPen,       gl->gpen,
  156.  
  157.             TAG_END) ;
  158. }
  159.  
  160. cstring::~cstring()
  161. {
  162.     if (norm1) delete norm1 ;
  163.     if (norm2) delete norm2 ;
  164.     if (under) delete under ;
  165.  
  166.     if (it1) delete it1 ;
  167.     if (it2) delete it2 ;
  168.     if (it3) delete it3 ;
  169.  
  170.     if (plain) delete plain ;
  171.     if (underline) delete underline ;
  172.  
  173.     if (gad) DisposeObject(gad) ;
  174.     if (font) CloseFont(font) ;
  175.     FreeELabel() ;
  176. }
  177.  
  178. void cstring::set(const char *text)
  179. {
  180.     SetGadgetAttrs((Gadget *)gad, w, NULL,
  181.         GA_Text,    text,
  182.         TAG_END) ;
  183. }
  184.  
  185. void cstring::keystroke(BOOL shifted)
  186. {
  187.     if (gfunc)
  188.         gadget::action(NULL, 0) ;
  189.     else
  190.         glist->selectgadget(id+1, shifted) ;
  191. }
  192.  
  193.  
  194. // ========================================================================
  195. // =============================== ELabel =================================
  196. // ========================================================================
  197.  
  198. struct ELabelINST {
  199.     IntuiText   *IText ;
  200.     TextFont    *TFont ;
  201.     STRPTR      Text ;
  202.     LONG        Val ;
  203.     LONG        Flags ;
  204.     BOOL        Border ;
  205.     UWORD       *XPens ;
  206.     UWORD       GPen ;
  207.     WORD        LeftEdge ;
  208.     WORD        TopEdge ;
  209.     WORD        Width ;
  210.     WORD        Height ;
  211.     BOOL        Drawable ;
  212.     BOOL        IsNum ;
  213.     BOOL        DrawAll ;
  214. } ;
  215.  
  216. static ULONG STDARGS dispatchELabel(Class *cl, Object *o, Msg msg);
  217. static ULONG   RenderELabel(Class *, Gadget *, gpRender *) ;
  218.  
  219. void  SetLims(ELabelINST *inst, Gadget *g, GadgetInfo *gi) ;
  220. static unsigned short ditherData[2] = {0x5555,0xAAAA};
  221.  
  222. static int ELabelCnt = 0 ;
  223. int InitELabel(void)
  224. {
  225.     if (ELabelCnt) {
  226.         ELabelCnt++ ;
  227.     }
  228.     else if (!(BOOPSIELabel = MakeClass(NULL, (UBYTE *)GADGETCLASS, NULL,
  229.         sizeof(ELabelINST), 0))) {
  230.         ELabelCnt = 0 ;
  231.     }
  232.     else {
  233.         BOOPSIELabel->cl_Dispatcher.h_Entry = (HOOKFUNC)HookEntry ;
  234.         BOOPSIELabel->cl_Dispatcher.h_SubEntry = (HOOKFUNC)dispatchELabel;
  235.         ELabelCnt = 1 ;
  236.     }
  237.     return ELabelCnt ;
  238. }
  239.  
  240. void FreeELabel(void)
  241. {
  242.     ELabelCnt-- ;
  243.     if (!ELabelCnt)
  244.         FreeClass(BOOPSIELabel) ;
  245. }
  246.  
  247. ULONG SAVEDS STDARGS dispatchELabel(  Class *cl, Object *o, Msg msg)
  248. {
  249. ELabelINST  *inst ;
  250. ULONG       retval = FALSE ;
  251. Object      *object ;
  252. TTextAttr   *ta ;
  253.  
  254.     GETA4 ;
  255.     switch (msg->MethodID) {
  256.     case OM_NEW:
  257.         if (object = (Object *)DoSuperMethodA(cl, o, msg)) {
  258.             Gadget *g = (Gadget *)object ;
  259.             inst = (ELabelINST *)INST_DATA(cl, object) ;
  260.             inst->IText = (IntuiText *)GetTagData(GA_IntuiText,
  261.                 NULL,
  262.                 ((opSet *)msg)->ops_AttrList) ;
  263.             inst->Flags = (LONG)GetTagData(EGA_Flags, PLACETEXT_LEFT,
  264.                     ((opSet *)msg)->ops_AttrList) ;
  265.             inst->Text = (STRPTR)GetTagData(GA_Text, NULL,
  266.                     ((opSet *)msg)->ops_AttrList) ;
  267.             inst->Border = (BOOL)GetTagData(GA_Border, FALSE,
  268.                     ((opSet *)msg)->ops_AttrList) ;
  269.             inst->XPens = (UWORD *)GetTagData(EGA_XPens, NULL,
  270.                     ((opSet *)msg)->ops_AttrList) ;
  271.  
  272.             inst->GPen = (UWORD)GetTagData(EGA_GPen, NULL,
  273.                     ((opSet *)msg)->ops_AttrList) ;
  274.  
  275.             inst->IsNum = BOOL(FindTagItem(EGA_Number,
  276.                                      ((opSet *)msg)->ops_AttrList) != NULL) ;
  277.             if (inst->IsNum)
  278.                 inst->Val = (LONG)GetTagData(EGA_Number, NULL,
  279.                     ((opSet *)msg)->ops_AttrList) ;
  280.  
  281.             inst->DrawAll = TRUE ;
  282.  
  283.             if (g->Flags & GFLG_RELRIGHT)
  284.                 g->LeftEdge = (short)GetTagData(GA_Left, g->LeftEdge, ((opSet *)msg)->ops_AttrList) ;
  285.             if (g->Flags & GFLG_RELHEIGHT)
  286.                 g->Height = (short)GetTagData(GA_Height, g->Height, ((opSet *)msg)->ops_AttrList) ;
  287.             if (g->Flags & GFLG_RELWIDTH)
  288.                 g->Width = (short)GetTagData(GA_Width, g->Width, ((opSet *)msg)->ops_AttrList) ;
  289.             if (g->Flags & GFLG_RELBOTTOM)
  290.                 g->TopEdge = (short)GetTagData(GA_Top, g->TopEdge, ((opSet *)msg)->ops_AttrList) ;
  291.  
  292.             ta = (TTextAttr *)GetTagData(EGA_TextAttr, NULL,
  293.                     ((opSet *)msg)->ops_AttrList) ;
  294.  
  295.             if (ta) {
  296.                 inst->TFont = OpenFont((TextAttr *)ta) ;
  297.             }
  298.             retval = (ULONG)object ;
  299.         }
  300.         break ;
  301.     case OM_DISPOSE:
  302.         inst = (ELabelINST *)INST_DATA(cl, o) ;
  303.         if (inst->TFont) CloseFont(inst->TFont) ;
  304.         retval = DoSuperMethodA(cl, o, msg) ;
  305.         break ;
  306.     case OM_SET:
  307.         retval = DoSuperMethodA(cl, o, msg) ;
  308.         if ( FindTagItem(GA_Text, ((opSet *)msg)->ops_AttrList) ||
  309.              FindTagItem(EGA_Number, ((opSet *)msg)->ops_AttrList) ) {
  310.             RastPort *rp ;
  311.             Gadget *g  = (Gadget *)o ;
  312.  
  313.             inst = (ELabelINST *)INST_DATA(cl, o) ;
  314.             inst->Text = (STRPTR)GetTagData(GA_Text, (ULONG)inst->Text, ((opSet *)msg)->ops_AttrList) ;
  315.             inst->Val = (LONG)GetTagData(EGA_Number, (ULONG)inst->Val, ((opSet *)msg)->ops_AttrList) ;
  316.             inst->DrawAll = FALSE ;
  317.  
  318.             if (rp = ObtainGIRPort( ((opSet *)msg)->ops_GInfo) ) {
  319.  
  320.                 DoMethod(o, GM_RENDER, ((opSet *)msg)->ops_GInfo, rp, GREDRAW_REDRAW) ;
  321.                 ReleaseGIRPort(rp) ;
  322.             }
  323.             inst->DrawAll = TRUE ;
  324.         }
  325.         break ;
  326.     case GM_RENDER:
  327.         retval = RenderELabel(cl, (Gadget *)o, (gpRender *)msg) ;
  328.         break ;
  329.     default :
  330.         retval = DoSuperMethodA(cl, o, msg) ;
  331.         break ;
  332.     }
  333.     return retval ;
  334. }
  335.  
  336.  
  337. ULONG SAVEDS RenderELabel(Class *cl, Gadget *g, gpRender *msg)
  338. {
  339. RastPort            *rp ;       // RastPort où le gadget est affiché
  340. ULONG               retval ;    // Code de retour
  341. UWORD               *pens ;     // pinceaux de l'écran
  342. UWORD               tpen ;      // couleur du texte
  343. ELabelINST          *inst ;     // pointeur sur les données
  344. IntuiText           *itext ;    // affichage du label
  345. LONG                l, t, len ; // left, top, len utilisés pour l'affichage
  346. struct TextExtent   te ;        // Calcul de la largeur du texte
  347.  
  348.  
  349.     GETA4 ;
  350.     // Initialisations
  351.  
  352.     // Affectation du RastPort selon la méthode d'appel
  353.  
  354.     if (msg->MethodID == GM_RENDER)
  355.         rp = msg->gpr_RPort ;
  356.     else
  357.         rp = ObtainGIRPort(msg->gpr_GInfo) ;
  358.  
  359.     if (rp) {
  360.  
  361.         retval = TRUE ;
  362.         pens = msg->gpr_GInfo->gi_DrInfo->dri_Pens ;
  363.         inst = (ELabelINST *)INST_DATA(cl, (Object *)g) ;
  364.  
  365.         tpen = inst->GPen ;
  366.         WaitTOF() ;
  367.         if (inst->DrawAll) {
  368.             EraseRect(rp, inst->LeftEdge, inst->TopEdge,
  369.                 inst->LeftEdge+inst->Width-1, inst->TopEdge+inst->Height-1) ;
  370.         }
  371.         else {
  372.             SetAPen(rp, (inst->Border)?inst->XPens[GFILL_PEN]:pens[BACKGROUNDPEN]) ;
  373.             RectFill(rp, inst->LeftEdge+2, inst->TopEdge+2,
  374.                 inst->LeftEdge+inst->Width-3, inst->TopEdge+inst->Height-3) ;
  375.         }
  376.         SetLims(inst, g, msg->gpr_GInfo) ;  // Calcul des limites
  377.         if (!inst->Drawable) {
  378.             retval = FALSE ;
  379.             goto out ;
  380.         }
  381.  
  382.         SetDrMd(rp, JAM2) ;
  383.         SetAPen(rp, pens[TEXTPEN]) ;
  384.         SetBPen(rp, (inst->Border)?inst->XPens[GFILL_PEN]:pens[BACKGROUNDPEN]) ;
  385.  
  386.         if (inst->Border && inst->DrawAll) {
  387.             SetAPen(rp, inst->XPens[GFILL_PEN]) ;
  388.             RectFill(rp, inst->LeftEdge+1, inst->TopEdge+1,
  389.                 inst->LeftEdge+inst->Width-2, inst->TopEdge+inst->Height-2) ;
  390.  
  391.             SetAPen(rp, pens[SHINEPEN]) ;
  392.  
  393.             Move(rp, inst->LeftEdge+1, inst->TopEdge+inst->Height-1) ;
  394.             Draw(rp, inst->LeftEdge+1, inst->TopEdge+1) ;
  395.             Draw(rp, inst->LeftEdge+inst->Width-1, inst->TopEdge+1) ;
  396.             Draw(rp, inst->LeftEdge+inst->Width-1, inst->TopEdge+inst->Height-1) ;
  397.             Draw(rp, inst->LeftEdge, inst->TopEdge+inst->Height-1) ;
  398.  
  399.             SetAPen(rp, pens[SHADOWPEN]) ;
  400.  
  401.             Move(rp, inst->LeftEdge, inst->TopEdge) ;
  402.             Draw(rp, inst->LeftEdge+inst->Width-2, inst->TopEdge) ;
  403.             Draw(rp, inst->LeftEdge+inst->Width-2, inst->TopEdge+inst->Height-2) ;
  404.             Draw(rp, inst->LeftEdge, inst->TopEdge+inst->Height-2) ;
  405.             Draw(rp, inst->LeftEdge, inst->TopEdge) ;
  406.         }
  407.  
  408.  
  409.         if (inst->IText) {  // Le gagdet possède un label
  410.             itext = inst->IText ;
  411.  
  412.             // recherche du dernier itext pour la longueur
  413.  
  414.             while (itext->NextText) itext = itext->NextText ;
  415.  
  416.             // Le calcul par défaut est pour PLACETEXT_IN
  417.  
  418.             len = IntuiTextLength(itext) + itext->LeftEdge ;
  419.             t = inst->TopEdge + 1 +
  420.                 (inst->Height - itext->ITextFont->ta_YSize -2) / 2 ;
  421.             l = inst->LeftEdge + 1 + (inst->Width - len - 2) / 2 ;
  422.  
  423.  
  424.             if (inst->Flags & PLACETEXT_RIGHT) {
  425.                 l = inst->LeftEdge + inst->Width + 4 ;
  426.             }
  427.             else if (inst->Flags & PLACETEXT_ABOVE) {
  428.                 t = inst->TopEdge - itext->ITextFont->ta_YSize - 4 ;
  429.             }
  430.             else if (inst->Flags & PLACETEXT_BELOW) {
  431.                 t = inst->TopEdge + inst->Height + 4 ;
  432.             }
  433.             else if (!(inst->Flags & PLACETEXT_IN)) {  // PLACETEXT_LEFT
  434.                 l = inst->LeftEdge - len - 4 ;
  435.             }
  436.             PrintIText(rp, inst->IText, l, t) ;
  437.         }
  438.         if (inst->IsNum) {
  439.         char text[20] ;
  440.             sprintf(text, "%ld", inst->Val) ;
  441.             SetAPen(rp, tpen) ; // Couleur du pinceau
  442.  
  443.             if (inst->TFont) SetFont(rp, inst->TFont) ;
  444.  
  445.  
  446.             len = (long)TextFit(rp, text,
  447.                 strlen(text), &te, NULL, 1,
  448.                  inst->Width-4, inst->Height-2) ;
  449.  
  450.  
  451.             l = inst->LeftEdge + (inst->Width - te.te_Width) / 2 ;
  452.             t = inst->TopEdge + (inst->Height -
  453.                     te.te_Extent.MinY - te.te_Extent.MaxY) / 2 ;
  454.  
  455.             Move(rp, l, t) ;
  456.             Text(rp, text, len) ;
  457.         }
  458.         else if (inst->Text) {   // Le gadget contient un texte
  459.  
  460.             SetAPen(rp, tpen) ; // Couleur du pinceau
  461.  
  462.             if (inst->TFont) SetFont(rp, inst->TFont) ;
  463.  
  464.             len = (long)TextFit(rp, inst->Text,
  465.                 strlen(inst->Text), &te, NULL, 1,
  466.                  inst->Width-4, inst->Height-2) ;
  467.  
  468.             if (inst->Width > te.te_Width)
  469.                 l = inst->LeftEdge + (inst->Width - te.te_Width) / 2 ;
  470.             else
  471.                 l = inst->LeftEdge+2 ;
  472.             t = inst->TopEdge + (inst->Height -
  473.                     te.te_Extent.MinY - te.te_Extent.MaxY) / 2 ;
  474.  
  475.             Move(rp, l, t) ;
  476.             Text(rp, inst->Text, len) ;
  477.         }
  478. out:
  479.         if (msg->MethodID != GM_RENDER)
  480.             ReleaseGIRPort(rp) ;
  481.     }
  482.     else
  483.         retval = FALSE ;
  484.     return retval ;
  485. }
  486.  
  487.  
  488. void SAVEDS SetLims(ELabelINST *inst, Gadget *g, GadgetInfo *gi)
  489. {
  490. long GLeft, GTop, GWidth, GHeight ;
  491.  
  492.     GETA4 ;
  493.     GLeft = g->LeftEdge ;
  494.     GTop = g->TopEdge ;
  495.     GWidth = g->Width  ;
  496.     GHeight = g->Height ;
  497.  
  498.     if (g->Flags & GFLG_RELRIGHT) {
  499.         GLeft = gi->gi_Window->Width - 1 ;
  500.         GLeft += g->LeftEdge ;
  501.     }
  502.  
  503.     if (g->Flags & GFLG_RELHEIGHT) {
  504.         GHeight = gi->gi_Window->Height ;
  505.         GHeight += g->Height ;
  506.     }
  507.  
  508.     if (g->Flags & GFLG_RELBOTTOM) {
  509.         GTop = gi->gi_Window->Height - 1 ;
  510.         GTop += g->TopEdge ;
  511.     }
  512.  
  513.     if (g->Flags & GFLG_RELWIDTH) {
  514.         GWidth = gi->gi_Window->Width ;
  515.         GWidth += g->Width ;
  516.     }
  517.     inst->Drawable = BOOL(GLeft >= 0 && GTop >= 0 &&
  518.         GWidth > 4 &&
  519.         GHeight > 4) ;
  520.     if (inst->Drawable) {
  521.         inst->LeftEdge = GLeft ;
  522.         inst->TopEdge = GTop ;
  523.         inst->Width = GWidth ;
  524.         inst->Height = GHeight ;
  525.     }
  526.  
  527. }
  528.